/**
 * @author roua_troua
 */

package q10.Visitor;

import q10.Operatori.*;
import q10.Arbori.Nod;
import q10.Functii.FunctiiElementare.*;
import q10.Functii.FunctiiTrigonometrice.*;


public class DerivareVisitor extends Visitor {
	protected String rezultatDeriv;
	protected ToStringVisitor tsv = new ToStringVisitor();
	/**
	 * Constructor
	 */
	public DerivareVisitor(){
		rezultatDeriv = "";
	}
	
	/**
	 * Constructor
	 * @param s
	 */
	public DerivareVisitor(String s){
		rezultatDeriv = s;
	}
	
	/**
	 * Metoda get
	 * @param
	 * @return String
	 */
	public String getRezultatDeriv(){
		return rezultatDeriv;
	}
	
	/**
	 * Metoda set
	 * @param r
	 * @return
	 */
	public void setRezultatDeriv(String r){
		rezultatDeriv = r;
	}
	
	
	/**
	 * visit Nod
	 * @param n Nod
	 * @return
	 */
	public void visit(Nod n){
		if (n.equals(new Plus()))
			visit(n);
		else if (n.equals(new Minus()))
			visit(n);
			else if (n.equals(new Cat()))
				visit(n);
			else if (n.equals(new Produs()))
				visit(n);
		
		if (n.equals(new Sin()))
			visit(n);
		else
			if (n.equals(new Cos()))
				visit(n);
		
		if (n.equals(new Constanta()))
			visit(n);
		else
			if (n.equals(new Necunoscuta()))
				visit(n);
			
	}
	
	
	/**
	 * Metoda visit Plus
	 * @param Plus p
	 * @return
	 */
	 
	public void visit(Plus p){
		if(p.getfStang() != null && p.getfDrept() != null){
			visit(p.getfStang());
			
			String s1 = this.rezultatDeriv;
			
			visit(p.getfDrept());
			
			String s2 = this.rezultatDeriv;
			rezultatDeriv = p.concatTermeni(s1, s2);
		}
	}
	
	/**
	 * Metoda visit Minus
	 * @param Minus m
	 * @return
	 */
	public void visit(Minus m){
		if(m.getfStang() != null && m.getfDrept() != null){
			visit(m.getfStang());
			
			String s1 = this.rezultatDeriv;
			
			visit(m.getfDrept());
			
			String s2 = this.rezultatDeriv;
			rezultatDeriv = m.concatTermeni(s1, s2);
		}
	}	
	
	/**
	 * Derivata Produsului
	 * @param p Produs
	 * 
	 */
	public void visit(Produs p){
		if(p.getfStang() != null && p.getfDrept() != null){
			visit(p.getfStang());			
			String f1D = this.rezultatDeriv;
			
			visit(p.getfDrept());
			String f2D = this.rezultatDeriv;
			
			p.getfStang().acceptVisitor(tsv);
			String f1 = tsv.getS();
			
			p.getfDrept().acceptVisitor(tsv);
			String f2 = tsv.getS();
			
			this.rezultatDeriv = Plus.concatTermens(Produs.concatTermens(f1D,f2),
					Produs.concatTermens(f1,f2D));
			
		}
	}
	
	/**
	 * @param c Cat
	 */
	public void visit(Cat c){
		if(c.getfStang() != null && c.getfDrept() != null){
			visit(c.getfStang());			
			String f1D = this.rezultatDeriv;
			
			visit(c.getfDrept());
			String f2D = this.rezultatDeriv;
			
			c.getfStang().acceptVisitor(tsv);
			String f1 = tsv.getS();
			
			c.getfDrept().acceptVisitor(tsv);
			String f2 = tsv.getS();
			
			this.rezultatDeriv = Cat.concatTermens(Minus.concatTermens(Produs.concatTermens(f1D,f2),
					Produs.concatTermens(f1,f2D)), Produs.concatTermens(f2, f2)) ;
			
		}
	}
	
	/**
	 * Derivata constantei
	 * @param ct Constanta
	 */
	public void visit(Constanta ct){
		this.rezultatDeriv = "0";
	}
	
	/**
	 * Derivata necunoscutei
	 * @param n Necunoscuta
	 */
	public void visit(Necunoscuta n){
		this.rezultatDeriv = "1";
	}
	
	/**
	 * derivata sinus
	 * @param sin Sin
	 */
	public void visit(Sin sin){
		if(sin.getfStang() != null){
			visit(sin.getfStang());
			String fsd = this.rezultatDeriv;
			
			sin.getfStang().acceptVisitor(tsv);
			String fs = tsv.getS();
			
			this.rezultatDeriv = Produs.concatTermens(Cos.concatTermens(fs), fsd);
		}					
	}
	
	public void visit(Cos cos){
		if(cos.getfStang() != null){
			visit(cos.getfStang());
			String fsd = this.rezultatDeriv;
			
			cos.getfStang().acceptVisitor(tsv);
			String fs = tsv.getS();
			
			this.rezultatDeriv = Minus.concatTermens("",Produs.concatTermens(Cos.concatTermens(fs),fsd)); 
				
		}
	}
	
	public void visit(Tg tg){
		
	}
	
	public void visit(Ctg ctg){
		
	}
}
